package com.iad.web;

// Core classes
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

// Servlet classes
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Commons classes
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.iad.entity.*;
import com.iad.persistence.SiteDAO;
import com.iad.service.SiteService;



public class UploadServlet extends HttpServlet  {
  // Called when a file has been submitted
  // Called because file uploads are HTTP POST operations
  public void doPost( HttpServletRequest req, HttpServletResponse res ) {
    // Setup the various objects used during this upload operation
    // Commons file upload classes are specifically instantiated
    File        disk = null;
    FileItem      item = null;
    FileItemFactory    factory = new DiskFileItemFactory();
    Iterator      iter = null;
    List        items = null;
    ServletFileUpload  upload = new ServletFileUpload( factory );
    ServletOutputStream  out = null;
    String path = "";
    String songName = "";
    String albumName = "";
    String playlistName = "";
    String videoName = "";
    String fileName = "";
    String siteId = "";
    String id = "";
    String playlistId = "";
    Boolean isNewSong = false;
    Boolean isNewPlaylist = false;
    Boolean isNewVideo = false;
    Boolean isVideoUpdate = false;
    Boolean isSiteImageUpdate = false;
    Boolean isSiteUpdate = false;
    Boolean isPlaylistUpdate = false;
    Boolean isPlaylistUpdateDetails = false;
    
    try 
    {
      // Parse the incoming HTTP request
      // Commons takes over incoming request at this point
      // Get an iterator for all the data that was sent
      // TODO: Leverage generics
      items = upload.parseRequest( req );    
      iter = items.iterator();
      
      // Set a response content type
      res.setContentType( "text/xml" );
      
      // Setup the output stream for the return XML data
      out = res.getOutputStream();
      out.println( "<response>" );
      System.out.println( "<response>" );
     
      while( iter.hasNext() ) {
        item = ( FileItem )iter.next();
        if (item.isFormField()) { 
          if (item.getFieldName().equals("path")) {
            path = item.getString(); 
          }
          else if (item.getFieldName().equals("songName")) {
            songName = item.getString(); 
          }
          else if (item.getFieldName().equals("isNewSong")) {
            isNewSong = true;
          }
          else if (item.getFieldName().equals("playlistName")) {
            playlistName = item.getString(); 
          }
          else if (item.getFieldName().equals("isNewPlaylist")) {
            isNewPlaylist = true;
          }
          else if (item.getFieldName().equals("albumName")) {
            albumName = item.getString(); 
          }
          else if (item.getFieldName().equals("Filename")) {
            fileName = item.getString(); 
          }
          else if (item.getFieldName().equals("id")) {
            id = item.getString();
          }
          else if (item.getFieldName().equals("siteId")) {
            siteId = item.getString();
          }
          else if (item.getFieldName().equals("playlistId")) {
            playlistId = item.getString();
          }
          else if (item.getFieldName().equals("videoName")) {
            videoName = item.getString();
          }
          else if (item.getFieldName().equals("isNewVideo")) {
            isNewVideo = true;
          }
          else if (item.getFieldName().equals("isVideoUpdate")) {
            isVideoUpdate = true;
          }
          else if (item.getFieldName().equals("isSiteUpdate")) {
            isSiteUpdate = true;
          }
          else if (item.getFieldName().equals("isSiteImageUpdate")) {
            isSiteImageUpdate = true;
          }
          else if (item.getFieldName().equals("isPlaylistUpdate")) {
            isPlaylistUpdate = true;
          }
          else if (item.getFieldName().equals("isPlaylistUpdateDetails")) {
            isPlaylistUpdateDetails = true;
          }
        }
      }
      iter = items.iterator();
    
      
      // Iterate through the incoming request data
      while (iter.hasNext()) {
        // Get the current item in the iteration
        item = ( FileItem )iter.next();
        
        // If the current item is an HTML form field
        if (item.isFormField()) {
          // Return an XML node with the field name and value
          out.println( "<field name=\"" + item.getFieldName() + "\" value=\"" + item.getString() + "\" />"  );
          System.out.println( "<field name=\"" + item.getFieldName() + "\" value=\"" + item.getString() + "\" />"  );
        
        // If the current item is file data
        } 
        else {
          // Specify where on disk to write the file
          // Using a servlet init param to specify location on disk
          // Write the file data to disk
          // TODO: Place restrictions on upload data
          disk = new File( getInitParameter("uploadPath") + path);
          item.write(disk);
          
          // Return an XML node with the file name and size (in bytes)
          out.println( "<file name=\"" + item.getName() + "\" size=\"" + item.getSize() + "\" />"  );
          System.out.println( "<file name=\"" + item.getName() + "\" size=\"" + item.getSize() + "\" />"  );
        }
      }
      
      
      if (isNewSong) {
        SiteService service = new SiteService();
        Song song = new Song();
        song.setName(songName);
        song.setAlbum(albumName);
        song.setPath(fileName);
        song.setSiteId(Long.parseLong(siteId));
        service.newSong(song);
        service.addSongToPlaylist(song, Long.parseLong(playlistId));
      }
      else if (isNewPlaylist) {
        SiteService service = new SiteService();
        Playlist playlist = new Playlist();
        playlist.setName(playlistName);
        playlist.setImagePath(fileName);
        playlist.setSiteId(Long.parseLong(siteId));
        service.newPlaylist(playlist);
      }
      else if (isNewVideo) {
        SiteService service = new SiteService();
        Video video = new Video();
        video.setPath(fileName);
        video.setName(videoName);
        video.setImagePath("new_playlist.jpg");
        video.setSiteId(Long.parseLong(siteId));
        service.newVideo(video);
      }
      else if (isVideoUpdate) {
        SiteService service = new SiteService();
        service.updateVideo(Long.parseLong(id), fileName);
      }
      else if (isPlaylistUpdate) {
        SiteService service = new SiteService();
        service.updatePlaylist(Long.parseLong(playlistId), fileName);
      }
      else if (isPlaylistUpdateDetails) {
        SiteService service = new SiteService();
        service.updatePlaylistDetails(Long.parseLong(siteId), fileName, playlistName);
      }
      else if (isSiteUpdate) {
        SiteService service = new SiteService();
        service.updateSite(Long.parseLong(siteId), fileName);
      }
      else if (isSiteImageUpdate) {
        SiteService service = new SiteService();
        service.updateSiteImage(Long.parseLong(siteId), fileName);
      }
      
      // Close off the response XML data and stream
      out.println( "</response>" );
      System.out.println( "</response>" );
      out.close();
      
      
    // Rudimentary handling of any exceptions
    // TODO: Something useful if an error occurs
    } catch( FileUploadException fue ) {
      fue.printStackTrace();
    } catch( IOException ioe ) {
      ioe.printStackTrace();
    } catch( Exception e ) {
      e.printStackTrace();
    }
  }
}
